<template>
  <div ref="slider" class="slider" @click.stop="handelClickSlider">
    <div class="process" :style="{ width }" />
    <div ref="thunk" class="thunk" :style="{ left }">
      <div ref="dot" class="block" :style="{ width: viewWidth }" />
    </div>
  </div>
</template>
<script setup name="Slider">
const props = defineProps({
  // 最小值
  min: {
    type: Number,
    default: 0,
  },
  // 最大值
  max: {
    type: Number,
    default: 100,
  },
  // 当前值
  modelValue: {
    type: Number,
    default: 0,
  },
  viewNum: {
    type: Number,
    default: 50,
  },
  // 是否可拖拽
  isDrag: {
    type: Boolean,
    default: true,
  },
})
const emit = defineEmits(['update:modelValue'])
const slider = ref(null) // 进度条DOM元素
const thunk = ref(null) // 拖拽DOM元素
const dot = ref(null)
const current = ref(props.modelValue) // 当前进度

const scale = computed(() => { // 进度占比多少
  return (current.value - props.min) / (props.max - props.min)
})
// 左侧部分已播放的宽度
const width = computed(() => {
  if (scale.value === 0) {
    return 0
  }
  return slider.value ? slider.value.offsetWidth * scale.value + thunk.value.offsetWidth / 2 + 'px' : 0
})
const viewWidth = computed(() => {
  return slider.value ? props.viewNum / props.max * slider.value.offsetWidth + 'px' : 0
})
const left = computed(() => {
  return slider.value ? slider.value.offsetWidth * scale.value + 'px' : 0;
})

watch(() => props.modelValue, (val) => {
  if (val > props.max - props.viewNum) {
    current.value = props.max - props.viewNum
    return
  }
  current.value = val
})

const handelClickSlider = (event) => {
  //禁止点击
  if (!props.isDrag) return;
  if (event.target == dot.value) return;
  //获取元素的宽度l
  const width = slider.value.offsetWidth;
  //获取元素的左边距
  const ev = event || window.event;
  //获取当前点击位置的百分比
  const scale = ((ev.offsetX / width) * 100).toFixed(2);
  current.value = scale * (props.max - props.min) / 100
}

onMounted(() => {
  if (!props.isDrag) return;
  thunk.value.onmousedown = (event) => {
    const oldWidth = parseInt(width.value);
    const disX = event.clientX;
    document.onmousemove = function (e) {
      // value, left, width
      // 当value变化的时候，会通过计算属性修改left，width
      // 拖拽的时候获取的新width
      const newWidth = e.clientX - disX + oldWidth;
      // 计算百分比
      const scale = newWidth / slider.value.offsetWidth;
      current.value = Math.ceil((props.max - props.min) * scale + props.min); //取整
      // 限制值大小
      current.value = Math.max(current.value, props.min);
      current.value = Math.min(current.value, props.max - props.viewNum);

      emit("update:modelValue", current.value);
    };
    document.onmouseup = function () {
      //清除拖拽事件
      document.onmousemove = document.onmouseup = null;
    };
  }
})
</script>
<style scoped>
.clear:after {
  content: "";
  display: block;
  clear: both;
}

.slider {
  position: relative;
  width: 100%;
  height: 6px;
  background: var(--scan-bg);
  border: 1px solid var(--play-bar-active);
  border-radius: 5px;
  cursor: pointer;
  z-index: 5;
}

.slider .process {
  position: absolute;
  left: 0;
  top: 0;
  width: 112px;
  height: 6px;
  border-radius: 5px;
  background: var(--play-bar-active);
  z-index: 111;
}

.slider .thunk {
  position: absolute;
  left: 100px;
  top: -4px;
  width: 10px;
  height: 4px;
  z-index: 122;
}

.slider .block {
  height: 12px;
  border-radius: 6px;
  background: #383838;
  border: 1px solid var(--play-bar-slider-border);
  transition: 0.2s all;
}

.slider .block:hover {
  transform: scale(1.1);
  opacity: 0.6;
}
</style>
